/*
 * @(#)MaintMultipleFileUploadAction.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.upload.web;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.SystemFunctionConstant;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.web.AbstractActionForm;
import com.dcivision.upload.core.MultipleFileUploadUtil;

public class MaintMultipleFileUploadAction extends com.dcivision.framework.web.AbstractMaintAction {

  public static final String REVISION = "$Revision: 1.11 $";

  public static final String STORAGE_ROOT = SystemParameterFactory.getSystemParameter(SystemParameterConstant.WORKFLOW_ATTACHMENT_PHYSICAL_PATH);

  /** Creates a new instance of MaintMultipleFileUploadAction */
  public MaintMultipleFileUploadAction() {
    super();
  }

  /** getFunctionCode
   *
   * Abstract function which sub-class should implement to return the corresponding
   * function code.
   *
   * @return   The function code
   */
  public String getFunctionCode() {
    return SystemFunctionConstant.WORKFLOW;
  }

  /** getMajorDAOClassName
   *
   * Abstract function which sub-class should implement to return the corresponding
   * major DAO class name used in this class.
   *
   * @return   The DAO class name
   */
  public String getMajorDAOClassName() {
    return "com.dcivision.workflow.dao.WorkflowProgressAttachmentDAObject";
  }

  public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException {
    AbstractActionForm maintForm = (AbstractActionForm)form;
    //set it for DMS include page.
    if("R".equals(maintForm.getOpMode())){
    	maintForm.setOpMode("");    
    }
    return super.execute(mapping,form,request,response); 
  }
  
  public void updateRecord(ActionMapping mapping, AbstractActionForm form, HttpServletRequest request, HttpServletResponse response) throws ApplicationException {
    try{
      log.debug("updateRecord!!!");
      MaintMultipleFileUploadForm maintForm = (MaintMultipleFileUploadForm) form;
      log.debug("maintForm idField: "+maintForm.getIdField());

      String filePath = this.createUploadTmpFolder(request);
      this.getUploadFileList(form, filePath);
      request.setAttribute("fileUploaded", Boolean.TRUE);


      log.debug("maintForm idField: "+maintForm.getIdField());
    } catch (Exception e) {
      log.debug("e: "+e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }
  }

  private String createUploadTmpFolder(HttpServletRequest request) throws ApplicationException {
    try {
      HttpSession session = request.getSession();
      String sessionID = session.getId();
      log.debug("storage root: "+STORAGE_ROOT);
      File storageRoot = new File(STORAGE_ROOT);
      if ( !(storageRoot.exists() && storageRoot.isDirectory()) ) {
        storageRoot.mkdir();
      }

      String storagePath = STORAGE_ROOT + "/" + sessionID;
      log.debug("storage path: "+storagePath);
      File storageFolder = new File(storagePath);
      if ( !(storageFolder.exists() && storageFolder.isDirectory()) ) {
        log.debug("storage folder ["+storagePath+"] is creating");
        boolean bCreateSuccess = storageFolder.mkdir();
      }
      return storagePath;
    } catch (Exception e) {
      log.debug("error in createUploadTmpFolder: "+e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    }

  }

  private void getUploadFileList(AbstractActionForm form, String filePath) throws ApplicationException {
    InputStream inputStream = null;
    FileOutputStream fos = null;
    int bufferSize = 8192;
    byte[] buffer = new byte[bufferSize];
    int length = -1;

    try {
      MaintMultipleFileUploadForm maintForm = (MaintMultipleFileUploadForm) form;
      MaintMultipleFileUploadForm tmpForm = new MaintMultipleFileUploadForm();
      List fileList = maintForm.getUploadedFileList();
      List nameList = maintForm.getFileNameList();

      for (int i=1; i<=maintForm.getDisplayListSize(); i++) {
        FormFile tmpFile=null;
        String tmpName=null;
        //log.debug("i="+i);

        //log.debug("class name: "+maintForm.getClass().toString());
        Method getFileMth = tmpForm.getClass().getMethod("getUploadFile"+i, null);
        //log.debug("get file method name: "+getFileMth.getName());
        Method getTrueFileNameMth = tmpForm.getClass().getMethod("getTrueFileName"+i, null);
        //log.debug("get true file method name: "+getFileMth.getName());
        tmpFile = (FormFile)getFileMth.invoke(maintForm, null);
        tmpName = (String)getTrueFileNameMth.invoke(maintForm, null);

        if (tmpFile != null) {
          if (!"".equals(tmpFile.getFileName())) {
            String convertedName = String.valueOf(System.currentTimeMillis() + i);
            String originalName = MultipleFileUploadUtil.getFileName(tmpName);

            log.debug("file name from form file: "+tmpName);
            
            File convertedFile = new File(filePath + "/" + convertedName);
            while(convertedFile.exists()){
              convertedName = convertedName + String.valueOf(System.currentTimeMillis());
              convertedFile = new File(filePath + "/" + convertedName);
            }            
            
            inputStream = tmpFile.getInputStream();
            fos = new FileOutputStream(convertedFile);
            while ((length=inputStream.read(buffer, 0, bufferSize)) != -1) {
              fos.write(buffer, 0, length);
            }
            fos.flush();
            inputStream.close();
            fos.close();

            HashMap nameMap = new HashMap();
            nameMap.put("convertedName", convertedName);
            nameMap.put("originalName", originalName);
            log.debug("nameMap="+nameMap);
            nameList.add(nameMap);
            fileList.add(tmpFile);
          }
        }
      }

      maintForm.setUploadedFileList(fileList);
      maintForm.setFileNameList(nameList);
      maintForm.setFormName(maintForm.getFormName());
      maintForm.setIdField(maintForm.getIdField());
      maintForm.setFileNames(maintForm.getFileNames());
    } catch (IOException ioe) {
      log.debug("io exception in getUploadFileList: "+ioe);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, ioe);
    } catch (Exception e) {
      log.debug("exception in getUploadFileList: "+e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR, e);
    } finally {
      try { inputStream.close(); } catch (Exception ignore) {}
      try { fos.close(); } catch (Exception ignore) {}
    }
  }
}
